import { useAtomValue } from 'jotai'
import { assistantListAtom, defaultPrompt } from '@/atoms'
import { useEffect, useState, useMemo } from 'react'
import { createPortal } from 'react-dom'
import { v7 as uuidv7 } from 'uuid'
import { Assistant } from '@/types'
import { modelTypes } from '@/funcs/models'
import { useTranslation } from 'react-i18next'
import PasswordTextField from '@/components/Base/PasswordTextField'
import useAssistant from '@/hooks/useAsisstant'
import {
  Divider, Button, Box,
  Dialog, DialogContent, DialogActions, DialogTitle,
  Select, MenuItem, InputLabel, FormControl,
  TextField, Autocomplete,
  Accordion, AccordionSummary, AccordionDetails,
} from '@mui/material'

const defaultItem = {
  id: '',
  name: '',
  modelApi: Object.keys(modelTypes)[0],
  modelName: '',
  apiKey: '',
  apiHost: '',
  prompt: defaultPrompt,
  mark: '',
}

let externalSetDialogOpen: (state: boolean) => void = () => {}
let extSetCurrentId: (id: string) => void = () => {}

const EditAssistantDialog: React.FC = () => {
  const { t } = useTranslation()
  const [open, setOpen] = useState(false)
  const [currentId, setCurrentId] = useState('')
  const [current, setCurrent] = useState<Assistant>(defaultItem)
  const assistants = useAtomValue(assistantListAtom)
  const { saveAssistants } = useAssistant()

  useEffect(() => {
    externalSetDialogOpen = setOpen
    extSetCurrentId = setCurrentId
  }, [])

  useMemo(() => {
    if (currentId) {
      const findIndex = assistants.findIndex(item => item.id == currentId)
      if (findIndex >= 0) {
        setCurrent(assistants[findIndex])
      }
      else {
        setCurrent({
          ...defaultItem,
          id: currentId,
        })
      }
    }
  }, [currentId])

  const onSave = () => {
    saveAssistants(current)
    setOpen(false)
  }

  if (!open || !current) return null

  return createPortal(
    <Dialog
      open
      onClose={() => setOpen(false)}
      fullWidth
    >
      <DialogTitle>{t('Assistant Settings')}</DialogTitle>
      <DialogContent>
        <Box className="flex flex-col gap-4 py-2">
          <TextField
            label={t('assistant name')}
            type="text"
            value={current.name}
            fullWidth
            required
            placeholder={t('assistant name placeholder')}
            onChange={e => setCurrent({ ...current, name: e.target.value })}
          />
          <Box className="flex gap-1">
            <FormControl className="w-1/2" required>
              <InputLabel>{t('mode api type')}</InputLabel>
              <Select
                value={current.modelApi}
                label={t('model api type')}
                renderValue={(val) => {
                  return val
                }}
                onChange={e => setCurrent({ ...current, modelApi: e.target.value })}
              >
                {Object.keys(modelTypes).map((model) => {
                  const typedModel = model as keyof typeof modelTypes
                  return (
                    <MenuItem value={typedModel} key={typedModel}>
                      <Box className="flex flex-col">
                        <Box>{modelTypes[typedModel].title}</Box>
                        <Box className="text-sm opacity-50">{modelTypes[typedModel].desc}</Box>
                      </Box>
                    </MenuItem>
                  )
                })}
              </Select>
            </FormControl>
            <Autocomplete
              disablePortal
              freeSolo={true}
              autoComplete
              options={Object.keys(modelTypes[current.modelApi as keyof typeof modelTypes].models)}
              onInputChange={(_, v) => {
                setCurrent({ ...current, modelName: v || '' })
              }}
              onChange={(_, v) => {
                setCurrent({ ...current, modelName: v || '' })
              }}
              value={current.modelName}
              sx={{ width: 300 }}
              renderInput={params => (
                <TextField
                  required
                  {...params}
                  label={t('model name')}
                />
              )}
            />
          </Box>
          <Divider />
          <PasswordTextField
            label="API Key"
            value={current.apiKey}
            placeholder="sk-xxxxxxxxxxxxxxxxxxxxxxxx"
            onChange={val => setCurrent({ ...current, apiKey: val })}
          />
          <TextField
            margin="dense"
            label="API Host"
            value={current.apiHost}
            fullWidth
            placeholder="https://api.openai.com"
            onChange={(e) => {
              let value = e.target.value
              value = value.trim()
              if (value.length > 4 && !value.startsWith('http')) {
                value = 'https://' + value
              }
              setCurrent({ ...current, apiHost: value })
            }}
          />
          <TextField
            margin="dense"
            label={t('assistant prompt label')}
            value={current.prompt}
            fullWidth
            multiline
            onChange={e => setCurrent({ ...current, prompt: e.target.value })}
          />
        </Box>
        <Accordion disableGutters>
          <AccordionSummary expandIcon={<div className="i-material-symbols:keyboard-arrow-down-rounded" />}>
            备注
          </AccordionSummary>
          <AccordionDetails>
            <TextField
              value={current.mark}
              fullWidth
              multiline
              onChange={e => setCurrent({ ...current, mark: e.target.value })}
            />
          </AccordionDetails>
        </Accordion>
      </DialogContent>
      <DialogActions>
        <Button onClick={() => setOpen(false)}>{t('dialog cancel btn')}</Button>
        <Button onClick={onSave}>{t('dialog ok btn')}</Button>
      </DialogActions>
    </Dialog>,
    document.body,
  )
}

export const showEditAssistantDialog = (id?: string) => {
  extSetCurrentId(id || uuidv7())
  externalSetDialogOpen(true)
}

export const hideEditAssistantDialog = () => {
  externalSetDialogOpen(false)
}

export default EditAssistantDialog
